package com.yzd.learnjava.concurrency;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.yzd.learnjava.concurrency.ListTest.Reader;
import com.yzd.learnjava.concurrency.ListTest.Writer;
import com.yzd.learnjava.util.CountingGenerator;
import com.yzd.learnjava.util.MapData;

public class MapComparisons {
	public static void main(String[] args) {
		Tester.initMain(args);
		
		new SynchronizedHashMapTest(10, 0);
		new SynchronizedHashMapTest(9, 1);
		new SynchronizedHashMapTest(5, 5);
		new ConcurrentHashMapTest(10, 0);
		new ConcurrentHashMapTest(9, 1);
		new ConcurrentHashMapTest(5, 5);
		
		Tester.exec.shutdown();
	}
}

abstract class MapTest extends Tester<Map<Integer, Integer>>{
	MapTest(String testId , int nResders , int nWriters){
		super(testId, nResders, nWriters);
	}
	
	class Reader extends Tester.TestTask{
		long result = 0;
		void test() {
			for(long i = 0 ; i < testCycles; i++) {
				for(int index = 0 ; index < containerSize; index++) {
					result += testContainer.get(index);
				}
			}
		}
		
		void putResults() {
			readResult += result;
			readTime += duration;
		}
	}
	
	class Writer extends Tester.TestTask{
		void test() {
			for(long i = 0 ; i < testCycles; i++) {
				for(int index = 0 ; index < containerSize; index++) {
					testContainer.put(index, writeData[index]);
				}
			}
		}
		void putResults() {
			writeTime += duration;
		}
	}
	
	void startReadersAndWriters() {
		for(int i = 0; i < nReaders; i++) {
			exec.execute(new Reader());
		}
		for(int i = 0 ; i < nWriters; i++) {
			exec.execute(new Writer());
		}
	}
}

class SynchronizedHashMapTest extends MapTest{
	Map<Integer, Integer> containerInitializer(){
		return Collections.synchronizedMap(
				new HashMap<Integer, Integer>(
						MapData.map(new CountingGenerator.Integer(), 
								new CountingGenerator.Integer(), 
								containerSize)));
	}
	SynchronizedHashMapTest(int nReaders, int nWriters){
		super("Synched HashMap", nReaders, nWriters);
	}
}

class ConcurrentHashMapTest extends MapTest{
	Map<Integer, Integer> containerInitializer(){
		return new ConcurrentHashMap<Integer, Integer>(
				MapData.map(
					new CountingGenerator.Integer(), 
					new CountingGenerator.Integer(), 
					containerSize));
	}
	ConcurrentHashMapTest(int nReaders, int nWriters){
		super("ConcurrentHashMap", nReaders, nWriters);
	}
}





























